﻿#include "ngx_http_huidu_module_handle.h"

#define weixin_appid_uri_prefix "/callback/"
#define weixin_appid_uri_suffix "/ticket.htm"

#define bbversion_appid		"appid"
#define bbversion_version	"appversion"
#define userid_key			"berbonAcc"


#define max_remote_cnt 		20
static char*  remote_key[] = {
		"X-Forwarded-For",
		"Proxy-Client-IP",
		"WL-Proxy-Client-IP",
		"X-Real-IP",
		NULL
};


#define no_ip_flag			"unknown"

#define IP_MAX_LEN 			 16

//functions
static ngx_int_t get_value_from_header(ngx_http_request_t *r, char *key, ngx_str_t *value);
static ngx_int_t get_first_ip_from_ips(ngx_http_request_t *r, ngx_str_t in, char *ip, int buf_len);
static void VS_StrRTrim(char *pStr);
static void VS_StrLTrim(char *pStr);
static ngx_int_t get_remote_ip(ngx_http_request_t *r,  char *ip, int buf_len);


#if 1
void printImInfo(ngx_http_request_t *r){

	ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
	             ">>>>>>>>>>printImInfo uri=%V,host=%V,exten = %V, ip=%V\n",
				 &(r->uri),
				 &(r->headers_in.host->value),
				 &(r->exten),
				 &(r->connection->addr_text));

	if(r->headers_in.user_agent != NULL)
		ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
		             ">>>>>>>>>>printImInfo user agent =%V\n", &(r->headers_in.user_agent->value));
}
#endif


/*去除字符串右边空格*/
static void
VS_StrRTrim(char *pStr) {
    char *pTmp = pStr+strlen(pStr)-1;

    while (*pTmp == ' ')
    {
        *pTmp = '\0';
        pTmp--;
    }
}

/*去除字符串左边空格*/
static void
VS_StrLTrim(char *pStr){
    char *pTmp = pStr;

    while (*pTmp == ' ')
    {
        pTmp++;
    }
    while(*pTmp != '\0')
    {
        *pStr = *pTmp;
        pStr++;
        pTmp++;
    }
    *pStr = '\0';
}
/*去除字符串前后空格*/
static void
VS_StrLRTrim(char *pStr){
	if(NULL == pStr) return;
	VS_StrLTrim(pStr);
	VS_StrRTrim(pStr);
}


ngx_int_t
str_cmp(u_char *ip1, u_char *ip2, size_t n1, size_t n2){

    if(n1 != n2) return -1;
    if(0 == ngx_memcmp(ip1, ip2, n1)){
        return 0;
    }
    return -1;
}
//从ip列表中 读取 第一个 非unknow的 ip
//获取请求的源ip
static ngx_int_t
get_first_ip_from_ips(ngx_http_request_t *r, ngx_str_t in, char *ip, int buf_len){

	char buf[512]={0};
	size_t	len = 0;
	char delims[] = ",";  //分隔符
	char *result = NULL;

	if(in.len == 0 || in.data == NULL) return 0;
	if(NULL == ip) return 0;

	len = in.len>511?511:in.len;
	memset(ip, 0, buf_len);
	memcpy(buf, in.data,len);
	buf[len]='\0';

	result = strtok( buf, delims);
	while( result != NULL) {
		ngx_log_error(NGX_LOG_DEBUG, r->connection->log, 0,  "get header ip  %s\n", result);
		if(strlen(result) != 0){
			VS_StrLRTrim(result);
			if(strlen(result)> 0 && ngx_strncasecmp((u_char *)result, (u_char *)no_ip_flag,strlen(no_ip_flag))){
				strncpy(ip,result, buf_len-1);
				return 1;
			}
		}
		result = strtok( NULL, delims );
	}
	return 0;


}
//获取请求的源ip
static ngx_int_t
get_remote_ip(ngx_http_request_t *r,  char *ip, int buf_len){

	ngx_str_t prox_ips;
	ngx_uint_t i = 0;
	prox_ips.data =NULL;
	prox_ips.len = 0;
	if(NULL == r){
		return 0;
	}

	for(i = 0; i< max_remote_cnt; i ++){
		if(remote_key[i] == NULL) break;
		if(get_value_from_header(r,remote_key[i],&prox_ips) && prox_ips.len>0){
			ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,  "get %s = %V\n", remote_key[i], &(prox_ips));
			if(get_first_ip_from_ips(r, prox_ips, ip, buf_len)){
				return 1;
			}
		}
	}
	memcpy(ip, r->connection->addr_text.data, r->connection->addr_text.len);
	ip[r->connection->addr_text.len] ='\0';
	return 1;
}
//当前数目很少 直接 遍历，若数据太多，后使用map或者排序后查找
static ngx_int_t
ip_list_check(ngx_http_request_t *r,ngx_str_t  *ip_list,  uint32_t count ){

    ngx_str_t *ips 	= NULL;
    uint32_t  i 	= 0;
    char remote_ip[24]={0};

    ips = ip_list;

    if(!get_remote_ip(r,remote_ip, 24)){
    	ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "ERROR!get_remote_ip return error, ip = %V\n", &(r->connection->addr_text));
    	            return 0;
    }
    ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,  "ip_list_check remote ip = %s\n", remote_ip);

    for(i =0; i < count; i ++){
        if(0 == str_cmp((u_char *)remote_ip,ips[i].data, strlen(remote_ip),ips[i].len)){
        	ngx_log_error(NGX_LOG_NOTICE, r->connection->log, 0, "ip_list_check find userid, uri = %V\n",&(r->uri));
            return 1;
        }
    }
    return 0;
}

static u_char *
find_str_in_str(u_char *src, size_t src_len, u_char *dst, size_t dst_len){

	int cmp_len ;
	int i;
	u_char *p;
	if(src_len < dst_len) return NULL;

	cmp_len = src_len - dst_len;
	p = src;
	for( i = 0 ; i <= cmp_len ; i ++){
		if(0 == ngx_memcmp(p, dst, dst_len))
			return p;

		p ++;
	}

	return NULL;

}


static ngx_int_t
get_appid_from_uri(ngx_http_request_t *r,ngx_str_t * result){

	u_char *suffix_start;
	u_char *prefix_start;
	ngx_int_t min_len = strlen(weixin_appid_uri_prefix) + strlen(weixin_appid_uri_suffix);

	if(r->uri.len <= (size_t)min_len){
		return 0;
	}
	suffix_start = find_str_in_str(r->uri.data,r->uri.len, (u_char *)weixin_appid_uri_suffix, strlen(weixin_appid_uri_suffix));
	if(suffix_start == NULL) {
		ngx_log_error(NGX_LOG_INFO,r->connection->log, 0,"get_appid_from_uri cant't find suffix_start \n");
		return 0;
	}

	prefix_start = find_str_in_str(r->uri.data,r->uri.len, (u_char *)weixin_appid_uri_prefix, strlen(weixin_appid_uri_prefix));
	if(prefix_start == NULL){
		ngx_log_error(NGX_LOG_INFO,r->connection->log, 0,"get_appid_from_uri cant't find prefix_start \n");
		return 0;
	}

	if(prefix_start != r->uri.data){
		ngx_log_error(NGX_LOG_ERR,r->connection->log, 0,"ERROR !find appid_uri_prefix but not at start\n");
		return 0;
	}
	if(prefix_start + strlen(weixin_appid_uri_prefix) >=  suffix_start) return 0;

	if(suffix_start == r->uri.data) return 0;

	result->len = suffix_start - r->uri.data - strlen(weixin_appid_uri_prefix);
	result->data = r->uri.data + strlen(weixin_appid_uri_prefix);

	ngx_log_error(NGX_LOG_INFO,r->connection->log, 0,"find appid from uri, uri=%V, appid=%V\n",  &(r->uri), result);

	return 1;

}



/*************************************************************************
 * 从报文头寻找指定的 字段的值
 ************************************************************************/
static ngx_int_t
get_value_from_header(ngx_http_request_t *r, char *key, ngx_str_t *value){


	ngx_list_part_t *h=NULL;
	ngx_uint_t 		i = 0;
	ngx_uint_t 		j = 0;
	ngx_table_elt_t *n;


	h= &(r->headers_in.headers.part);


	for(i =0 ;i <r->headers_in.headers.nalloc; i++ ){
		if(h == NULL) break;
		n = h->elts;
		for(j = 0; j< h->nelts; j ++){
			ngx_log_error(NGX_LOG_DEBUG,r->connection->log, 0,"get_value_from_header  key = %V,value=%V \n",&(n[j].key), &(n[j].value));

			if(0 == str_cmp((u_char*)key, n[j].key.data, strlen(key), n[j].key.len)){
				value->data = n[j].value.data;
				value->len = n[j].value.len;
				return 1;
			}
		}

		h = h->next;
	}

	return 0;
}



static ngx_int_t
get_value_from_cookies(ngx_http_request_t *r, char *key, ngx_str_t *value){

	ngx_table_elt_t ** cookies = NULL;
	ngx_uint_t i =0;
	u_char * key_pos=NULL;
	u_char * value_pos=NULL;
	u_char * pos=NULL;
	u_char * cookies_end=NULL;
	ngx_uint_t  value_len=0;

	ngx_log_error(NGX_LOG_INFO,r->connection->log, 0,"get_value_from_cookies Cookie count: %d \n",r->headers_in.cookies.nelts);

	cookies = r->headers_in.cookies.elts;
	for (i = 0 ; i < r->headers_in.cookies.nelts; i++) {
		ngx_log_error(NGX_LOG_INFO,r->connection->log, 0,"get_value_from_cookies Cookie line %d: %V\n",i, &(cookies[i]->value));

		value_len = 0;
		value_pos=NULL;
		key_pos = find_str_in_str(cookies[i]->value.data, cookies[i]->value.len, (u_char *)key, strlen(key));
		cookies_end = cookies[i]->value.data + cookies[i]->value.len;


		if(key_pos != NULL && key_pos < cookies_end){
			//寻找value
			pos = key_pos + strlen(key);
			while(pos <= cookies_end){
				if(value_pos == NULL){
					if(*pos == ';')
						break;
					else if(*pos == '=')
						value_pos = pos+1;

					pos ++;
				}
				else{
					if(*pos == ';' || pos == cookies_end){
						value->data = value_pos;
						value->len = value_len;

						ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, "get_value_from_cookies   key =[%s], value =[%V]\n",key, value);

						return 1;
					}
					else if(*pos == '='){
						ngx_log_error(NGX_LOG_ERR,r->connection->log, 0,"find Cookie error! line %d: %V\n",i, &(cookies[i]->value));
						break;
					}
					else{
						value_len ++;
					}
					pos ++;
				}
			}
		}
	}

	return 0;
}

static ngx_int_t
get_value_from_one_url_args(ngx_http_request_t *r,u_char *arg,  size_t len,  char *key, ngx_str_t *value ){

	ngx_uint_t key_len= 0;
	key_len = strlen(key);
	ngx_str_t tmp;
	tmp.len = len;
	tmp.data = arg;
	ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, "get_value_from_one_url_args  arg ->[%V]\n",&(tmp));

	if(len < (key_len+1)) return 0;

	if((0 == str_cmp((u_char*)key, arg, key_len, key_len))&&
			(*(arg+key_len) == '=')){
		if(len == key_len+1) return 0;

		value->data = arg+key_len+1;
		value->len = len-key_len-1;

		return 1;
	}

	return 0;
}

static ngx_int_t
get_value_from_url(ngx_http_request_t *r, char *key, ngx_str_t *value){

	ngx_uint_t i =0;
	u_char *arg_start = NULL;
	u_char *cur_pos = NULL;
	ngx_uint_t len = 0;
	ngx_log_error(NGX_LOG_INFO,r->connection->log, 0,"get_value_from_url  args[%V] \n",&(r->args));

	arg_start = r->args.data;
	for(i =0; i < r->args.len;i ++){
		cur_pos = r->args.data + i;
		if(*cur_pos == '&'){
			len = cur_pos - arg_start;
			if(get_value_from_one_url_args(r,arg_start, len, key , value)){
				ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, "get_value_from_url   key =[%s], value =[%V]\n",key, value);
				return 1;

			}
			arg_start = cur_pos +1;
		}
		else if(i== (r->args.len -1)){
			len = cur_pos - arg_start +1;
			if(get_value_from_one_url_args(r,arg_start, len, key , value)){
				ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, "get_value_from_url   key =[%s], value =[%V]\n",key, value);
				return 1;
			}
			return 0;
		}

	}

	return 0;

}


static ngx_int_t
appid_list_check(ngx_http_request_t *r,ngx_str_t  *appid_list,  uint32_t count ){

    ngx_str_t *appids = NULL;
    uint32_t    i = 0;
    appids = appid_list;
    ngx_str_t cur_appid;

    ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
                          "appid_list_check cur uri = %V \n", &(r->uri));

    if(! get_appid_from_uri(r, &cur_appid)) return 0;


    for(i =0; i < count; i ++){
        if(0 == str_cmp(cur_appid.data,
        	appids[i].data,
			cur_appid.len,
			appids[i].len)){
        		ngx_log_error(NGX_LOG_NOTICE, r->connection->log, 0, "appid_list_check   find userid, uri = %V\n",&(r->uri));
        		return 1;
        }
    }
    return 0;
}

static ngx_int_t
bbversion_list_check(ngx_http_request_t *r,ngx_str_t  *bbversion_list,  uint32_t count ){

    ngx_str_t *bbversions = NULL;
    uint32_t    i 	= 0;
    bbversions 		= bbversion_list;
    ngx_str_t cur_appid;
    ngx_str_t cur_appversion;

    u_char bbversion[256]={0};
    uint32_t len = 0;
    uint32_t    find_bbcersion	= 0;

    ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, "bbversion_list cur uri = %V \n", &(r->uri));
    cur_appid.len = 0;
    cur_appversion.len = 0;

   do{
    	 //首先查找header
    	for(i = 0; i< 1; i++){
    		if(!get_value_from_header(r, bbversion_appid, &cur_appid)){
					ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, "bbversion_list_check  get_value_from_header  can't find bbversion_appid  return 0\n");
					break;
			}

			ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, "bbversion_list_check get_value_from_header  find bbversion_appid[%V]\n", &(cur_appid));
			find_bbcersion = 1;
			if(!get_value_from_header(r, bbversion_version, &cur_appversion)){
				ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, "bbversion_list_check get_value_from_header  can't find cur_appversion  getdefault value\n");
				cur_appversion.len = 0;
				cur_appversion.data = NULL;
			}
			else
				ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, "bbversion_list_check get_value_from_header find bbversion_version[%V]\n", &(cur_appversion));

    	};

    	if(find_bbcersion) break;
		//再查找url

    	for(i = 0; i< 1; i++){
			if(!get_value_from_url(r, bbversion_appid, &cur_appid)){
					ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, "bbversion_list_check get_value_from_url  can't find bbversion_appid  return 0\n");
					break;
			}

			ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, "bbversion_list_check get_value_from_url find bbversion_appid[%V]\n", &(cur_appid));
			find_bbcersion = 1;
			if(!get_value_from_url(r, bbversion_version, &cur_appversion)){
				ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, "bbversion_list_check get_value_from_url  can't find cur_appversion  use default \n");
				cur_appversion.len = 0;
				cur_appversion.data = NULL;
			}
			else
				ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, "bbversion_list_check get_value_from_url find bbversion_version[%V]\n", &(cur_appversion));

    	};

		if(find_bbcersion) break;
		//最后查找cookies
		for(i = 0; i< 1; i++){
			if(!get_value_from_cookies(r, bbversion_appid, &cur_appid)){
					ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, "bbversion_list_check get_value_from_cookies  can't find bbversion_appid  return 0\n");
					break;
			}

			ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, "bbversion_list_check get_value_from_cookies find bbversion_appid[%V]\n", &(cur_appid));
			find_bbcersion = 1;
			if(!get_value_from_cookies(r, bbversion_version, &cur_appversion)){
				ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, "bbversion_list_check get_value_from_cookies  can't find cur_appversion  return 0 \n");
				cur_appversion.len = 0;
				cur_appversion.data = NULL;
			}
			else
				ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, "bbversion_list_check get_value_from_cookies find bbversion_version[%V]\n", &(cur_appversion));

		};


    }while(0);

   if(cur_appid.len == 0) return 0;

   len = cur_appid.len + cur_appversion.len +1;
   if(len >= 256) {
      	  ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "ERROR ! bbversion fuffer too small%V\n");
      	  return 0;
   }

    //拷贝字符串
    memcpy(bbversion, cur_appid.data, cur_appid.len);
    memcpy(bbversion + cur_appid.len, "|", 1);
    if(cur_appversion.len > 0)
    	memcpy(bbversion + cur_appid.len +1, cur_appversion.data, cur_appversion.len);

    ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, "bbversion =[%s] \n",bbversion);

    //获取appversion
    //获取
    for(i =0; i < count; i ++){

        if(0 == str_cmp(bbversion,
        	bbversions[i].data,
			len,
			bbversions[i].len)){
        	ngx_log_error(NGX_LOG_NOTICE, r->connection->log, 0, "bbversion_list_check   find userid, uri = %V\n",&(r->uri));
            return 1;
        }
    }
    return 0;
}



static ngx_int_t
userid_list_check(ngx_http_request_t *r,ngx_str_t  *user_id_list,  uint32_t count ){
#if 0

	ngx_str_t *userids = NULL;
	uint32_t    i 	= 0;
	userids 		= user_id_list;
	ngx_str_t cur_id;
	ngx_str_t cur_appid;
	ngx_str_t cur_appversion;

	u_char 		userid[256]={0};
	uint32_t 	len = 0;
	uint32_t    find_userid	= 0;

	ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, "userid_list_check cur uri = %V \n", &(r->uri));
	cur_id.len = 0;
	cur_appid.len = 0;
	cur_appversion.len = 0;

   do{
	   //首先查找userid
	   if(!get_value_from_cookies(r, userid_key, &cur_id)){
	   		ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, "userid_list_check get_value_from_cookies  can't find bbversion_appid  return 0\n");
	   		return 0;
	   	}

	   ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, "userid_list_check get_value_from_header  find userid_id[%V]\n", &(cur_id));

		//首先查找header
		for(i = 0; i< 1; i++){
			if(!get_value_from_header(r, bbversion_appid, &cur_appid)){
					ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, "userid_list_check  get_value_from_header  can't find bbversion_appid  return 0\n");
					break;
			}

			ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, "userid_list_check get_value_from_header  find bbversion_appid[%V]\n", &(cur_appid));
			find_userid = 1;
			if(!get_value_from_header(r, bbversion_version, &cur_appversion)){
				ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, "userid_list_check get_value_from_header  can't find cur_appversion  getdefault value\n");
				cur_appversion.len = 0;
				cur_appversion.data = NULL;
			}
			else
				ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, "userid_list_check get_value_from_header find bbversion_version[%V]\n", &(cur_appversion));

		};

		if(find_userid) break;
		//再查找url

		for(i = 0; i< 1; i++){
			if(!get_value_from_url(r, bbversion_appid, &cur_appid)){
					ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, "userid_list_check get_value_from_url  can't find bbversion_appid  return 0\n");
					break;
			}

			ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, "userid_list_check get_value_from_url find bbversion_appid[%V]\n", &(cur_appid));
			find_userid = 1;
			if(!get_value_from_url(r, bbversion_version, &cur_appversion)){
				ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, "userid_list_check get_value_from_url  can't find cur_appversion  use default \n");
				cur_appversion.len = 0;
				cur_appversion.data = NULL;
			}
			else
				ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, "userid_list_check get_value_from_url find bbversion_version[%V]\n", &(cur_appversion));

		};

		if(find_userid) break;
		//最后查找cookies
		for(i = 0; i< 1; i++){
			if(!get_value_from_cookies(r, bbversion_appid, &cur_appid)){
					ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, "userid_list_check get_value_from_cookies  can't find bbversion_appid  return 0\n");
					break;
			}

			ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, "userid_list_check get_value_from_cookies find bbversion_appid[%V]\n", &(cur_appid));
			find_userid = 1;
			if(!get_value_from_cookies(r, bbversion_version, &cur_appversion)){
				ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, "userid_list_check get_value_from_cookies  can't find cur_appversion  return 0 \n");
				cur_appversion.len = 0;
				cur_appversion.data = NULL;
			}
			else
				ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, "userid_list_check get_value_from_cookies find bbversion_version[%V]\n", &(cur_appversion));

		};


	}while(0);

   if(cur_appid.len == 0 || cur_id.len == 0) return 0;

   len = cur_id.len +cur_appid.len + cur_appversion.len +2;
   if(len >= 256) {
		  ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "ERROR ! userid_list_check fuffer too small%V\n");
		  return 0;
   }

	//拷贝字符串
   	memcpy(userid,  cur_id.data,  cur_id.len);
   	memcpy(userid +  cur_id.len, "|", 1);
	memcpy(userid +  cur_id.len + 1, cur_appid.data, cur_appid.len);
	memcpy(userid +  cur_id.len + 1+cur_appid.len, "|", 1);
	if(cur_appversion.len > 0)
		memcpy(userid +  cur_id.len + 1+cur_appid.len+1, cur_appversion.data, cur_appversion.len);

	ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, "userid =[%s] \n",userid);

	//获取appversion
	//获取
	for(i =0; i < count; i ++){

		if(0 == str_cmp(userid,
				userids[i].data,
			len,
			userids[i].len)){
			ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, "userid_list_check   find userid\n");
			return 1;
		}
	}
	return 0;

#endif

	ngx_str_t *userids = NULL;
	uint32_t    i = 0;
	userids = user_id_list;
	ngx_str_t cur_userid;
	cur_userid.data = NULL;
	cur_userid.len = 0;

	ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
						  "userid_list_check cur uri = %V \n", &(r->uri));

	if(!get_value_from_cookies(r, userid_key, &cur_userid)) return 0;
	if(cur_userid.len == 0) return 0;

	for(i =0; i < count; i ++){
		if(0 == str_cmp(cur_userid.data,
				userids[i].data,
				cur_userid.len,
				userids[i].len)){
			ngx_log_error(NGX_LOG_NOTICE, r->connection->log, 0, "userid_list_check   find userid, uri = %V\n",&(r->uri));
			return 1;
		}
	}
	return 0;
}


static ngx_int_t
check_request(ngx_http_request_t *r,huidu_limit_info_t *huidu_config){
	if(huidu_config == NULL) return 0;

	if(userid_list_check(r,
				huidu_config->user_id_list.data,
				huidu_config->user_id_list.cnt))
			return 1;

	if(ip_list_check(r,
			huidu_config->ip_list.data,
			huidu_config->ip_list.cnt))
		return 1;

	if(appid_list_check(r,
			huidu_config->appid_list.data,
			huidu_config->appid_list.cnt))
		return 1;

	if(bbversion_list_check(r,
			huidu_config->bbversion_list.data,
			huidu_config->bbversion_list.cnt))
		return 1;

	return 0;

}


static void
make_header_token(ngx_http_request_t *r, ngx_http_huidu_conf_t *scf){

	 ngx_table_elt_t                      *h;
	 ngx_str_t name = scf->header_key;
	 ngx_str_t value = scf->header_value;

	// ngx_str_t name = ngx_string("huiduflag" );
	// ngx_str_t value = ngx_string("yes" );


	 h = ngx_list_push(&r-> headers_in.headers );
	 if(h == NULL){
		ngx_log_error(NGX_LOG_ERR,r->connection->log, 0,"ERROR !make_header_token error!");
		return ;
	 }

     h->key.len = name.len;
     h->value.len = value.len;
     h->key.data = ngx_pnalloc(r->pool,h->key.len + 1 + h->value.len + 1 + h->key.len+ h->key.len);
     if (h->key.data == NULL) {
    	 ngx_log_error(NGX_LOG_ERR,r->connection->log, 0,"ERROR !ngx_pnalloc(key.data) return null!!!");
         return ;
     }

     h->value.data = h->key.data + h->key.len + 1;
     h->lowcase_key = h->key.data + h->key.len + 1 + h->value.len + 1;
     ngx_memcpy(h->key.data, name.data, h->key.len);
     h->key.data[h->key.len] = '\0';
     ngx_memcpy(h->value.data, value.data, h->value.len);
     h->value.data[h->value.len] = '\0';

     h->lowcase_key = ngx_pnalloc(r->pool, h->key.len);
	 if(h->lowcase_key == NULL) {
		 ngx_log_error(NGX_LOG_ERR,r->connection->log, 0,"ERROR !ngx_pnalloc(h->lowcase_key) return null!!!");
		 return;
	 }
     h->hash = r->header_hash;
     ngx_strlow(h->lowcase_key, h->key.data, h->key.len);

     /*


	 h-> hash = 1;
	 h-> key.len = name.len;
	 h-> key.data = name.data;
	 h-> value.len = value.len;
	 h-> value.data = value.data;
	 */
}


void
huidu_request_handle(ngx_http_request_t *r,
		ngx_http_huidu_conf_t    *scf,
		huidu_limit_info_t *huidu_config){

    ngx_uint_t 					i;

	if(huidu_config == NULL) {
		ngx_log_error(NGX_LOG_ERR,r->connection->log, 0,"ERROR !ngx_http_huidu_handler g_huidu_config = null");
		return;
	}

	if(check_request(r, huidu_config)){
		ngx_log_error(NGX_LOG_NOTICE, r->connection->log, 0,
			             "NOTICE!Current request is gray!  uri=%V,host=%V,exten = %V, ip=%V\n",
						 &(r->uri),
						 &(r->headers_in.host->value),
						 &(r->exten),
						 &(r->connection->addr_text));

		make_header_token(r,scf);
	}


#if 1

	//for test
	for(i =0 ;i < huidu_config->ip_list.cnt; i ++){
		 ngx_log_error(NGX_LOG_INFO,  r->connection->log, 0,"***get ip_list key=%V \n", &(huidu_config->ip_list.data[i]));
	}
	 for(i =0 ;i < huidu_config->user_id_list.cnt; i ++){
		 ngx_log_error(NGX_LOG_INFO,  r->connection->log, 0,"***get user_id_list  = %V\n", &(huidu_config->user_id_list.data[i]));
	}

	for(i =0 ;i < huidu_config->appid_list.cnt; i ++){
		ngx_log_error(NGX_LOG_INFO,  r->connection->log, 0,"***get appid_list  = %V\n", &(huidu_config->appid_list.data[i]));
	}

	 for(i =0 ;i < huidu_config->bbversion_list.cnt; i ++){
		ngx_log_error(NGX_LOG_INFO,  r->connection->log, 0,"***get bbversion_list  = %V\n", &(huidu_config->bbversion_list.data[i]));
	}



#endif

	return;



}
